package com.example.batch.core.transaction;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;
import org.springframework.transaction.PlatformTransactionManager;
import org.springframework.transaction.TransactionDefinition;
import org.springframework.transaction.TransactionStatus;
import org.springframework.transaction.support.TransactionSynchronizationManager;

import java.util.Map;

@Component
public class MultipleTransactionManager implements PlatformTransactionManager {

    private final Map<TransactionType, PlatformTransactionManager> transactionManagers;
    private final TransactionSynchronizationManager synchronizationManager;
    
    public MultipleTransactionManager(
            @Autowired XATransactionManager xaTransactionManager,
            @Autowired ChainedTransactionManager chainedTransactionManager,
            @Autowired BestEffortTransactionManager bestEffortTransactionManager) {
        this.transactionManagers = Map.of(
            TransactionType.XA, xaTransactionManager,
            TransactionType.CHAINED, chainedTransactionManager,
            TransactionType.BEST_EFFORT, bestEffortTransactionManager
        );
        this.synchronizationManager = new TransactionSynchronizationManager();
    }
    
    @Override
    public TransactionStatus getTransaction(TransactionDefinition definition) {
        TransactionType type = determineTransactionType(definition);
        PlatformTransactionManager manager = transactionManagers.get(type);
        
        if (manager == null) {
            throw new IllegalStateException("No transaction manager found for type: " + type);
        }
        
        synchronizationManager.initSynchronization();
        try {
            return manager.getTransaction(definition);
        } catch (Exception e) {
            synchronizationManager.clearSynchronization();
            throw e;
        }
    }
    
    private TransactionType determineTransactionType(TransactionDefinition definition) {
        // 根据事务定义和当前上下文决定使用哪种事务类型
        if (definition.getTimeout() > 30) {
            return TransactionType.BEST_EFFORT;
        }
        if (isMultipleDataSourcesInvolved()) {
            return TransactionType.XA;
        }
        return TransactionType.CHAINED;
    }
} 